package memory

import (
	"sync"
	"container/list"
	"time"
)

type Provider struct {
	lock     sync.Mutex               // 用来锁
	sessions map[string]*list.Element //用来存储在内存
	list     *list.List               // 用来做GC
}

func (provider *Provider) SessionInit(sid string) (Session, error) {
	provider.lock.Lock()
	defer provider.lock.Unlock()

	v := make(map[interface{}]interface{}, 0)
	newsess := &SessionStore{sid: sid, timeAccessed: time.Now(), value: v}
	element := provider.list.PushBack(newsess)
	provider.sessions[sid] = element

	return newsess, nil
}

func (provider *Provider) SessionRead(sid string) (Session, error) {
	if element, ok := provider.sessions[sid]; ok {
		return element.Value.(*SessionStore), nil
	} else {
		return provider.SessionInit(sid)
	}

	return nil, nil
}

func (provider Provider) SessionDestroy(sid string) error {
	if element, ok := provider.sessions[sid]; ok {
		delete(provider.sessions, sid)
		provider.list.Remove(element)
		return nil
	}
	return nil
}

func (provider Provider) SessionGC(maxlifetime int64) {
	provider.lock.Lock()
	defer provider.lock.Unlock()

	for {
		element := provider.list.Back()
		if(element == nil) {
			break;
		}
		if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() {
			provider.list.Remove(element)
			delete(provider.sessions, element.Value.(*SessionStore).sid)
		} else {
//			break;
		}
	}
}